<template>
	<view>
		<page-head title="view"></page-head>
		<view style="font-size: 28px; text-align: center;margin-top: 200px;" @tap="getRecordAuth">录音(麦克风)授权</view>
		<view style="font-size: 28px; text-align: center" @tap="clearContent">清除内容</view>
		<view style="font-size: 28px; text-align: center" @tap="start">开始录音1</view>
		<view style="font-size: 28px; text-align: center" @tap="stop">结束录音</view>
		<view>
			{{ content + addContent }}
		</view>
	</view>
</template>
<script>
	// 引入录音对象
	/* #ifdef APP-PLUS */
	import Record from './record.js';
	/* #endif */
	const {
		authForApp
	} = require('./appPermission.js');
	// 腾讯云asr识别对象
	import TengxunAsr from './TengxunAsr';
	let recorderManager = null;
	let asr = null;
	export default {
		// 组件名称
		name: '',
		// 局部注册的组件
		components: {},
		// 组件参数 接收来自父组件的数据
		props: {},
		// 组件状态值
		data() {
			return {
				content: '',
				addContent: '',
				// 入参设置成响应式，你根据业务自己随意更改
				asrParams: {
					hotword_id: "7877d77dc4c311e9e0c525400aec391",
					customization_id: "7877d77dc4c311e9e0c525400aec391",
					hotword_list: ''
				}
			};
		},
		// 计算属性
		computed: {},
		// 侦听器
		watch: {},
		mounted() {
			// 这里是使用即时识别语音的，不使用的话就直接注释这个asrinit就只是单纯录音。
			// 如果你是使用腾讯云sdk即时识别语音的，自己补充new TengxunAsr的四个入参
			this.asrInit();
			this.recorderInit();
		},

		destroyed() {
			recorderManager.destroyed();
			asr?.close();
		},
		// 组件方法
		methods: {
			clearContent() {
				this.content = '';
				this.addContent = '';
			},
			asrInit() {
				// 初始化腾讯云asr,输入必要的参数
				asr = new TengxunAsr({
					secretKey: 'V2X3d8ulhirvtkVFtPygTJa0Nl6bCHVe',
					secretId: 'AKIDDYp3Nf0FR4vpeNzW9gK1oYSMCHONMKNB',
					appId: '1323065199'
				});

				// asr,有open和close两个主要方法
				asr.init({
					onOpen: res => {},
					onMessage: res => {
						console.log('第三方的asr返回的数据：', res);

						// 科大讯飞返回结果处理,不需要删除
						if (asr.type === '讯飞') {}

						// 阿里云返回结果处理,不需要删除
						if (asr.type === 'ali') {
							if (res.header.name === 'TranscriptionResultChanged') {
								console.log('%c Line:92 🍓 TranscriptionResultChanged=============', res
									.payload.result);
								this.addContent = res.payload.result;
							} else if (res.header.name === 'TranscriptionStarted') {
								// 'frameSize'：int,//帧大小（必须，单位：字节）
								// 'sampleRate':int，//采样率（16000采样率插件写死16000）8000采样率插件的要写死8000
								// 'duration':number // 默认录音时间
								// 生成的录音格式一律是pcm，这种格式基本兼容所有市场的asr第三方
								// app端录音需要这是四个参数，其他参数内置好了默认值。不建议修改，因为这种配置比较稳定
								// 微信小程序端可以根据微信小程序文档自行写入参
								recorderManager.start({
									frameSize: 1024 * 5,
									duration: 30 * 60 * 1000,
									sampleRate: 16000,
									format: 'pcm'
								});
							} else if (res.header.name === 'SentenceEnd') {
								console.log('%c Line:94 🥓 SentenceEnd====================', res.payload
									.result);
								this.content = this.content + res.payload.result;
								this.addContent = '';
							}
						}

						// 不同第三方的asr返回的文字数据的字段不一样，腾讯云是voice_text_str,阿里云可能是其他，自己根据对应文档去写 腾讯云asr返回结果的，不需要删除
						if (asr.type === 'tengxun') {
							const {
								voice_text_str = ''
							} = res.result || {};
							this.addContent = voice_text_str;
						}
					},
					onClose: res => {}
				});
			},
			recorderInit() {
				/* #ifdef MP-WEIXIN */
				recorderManager = uni.getRecorderManager();
				/* #endif */
				/* #ifdef APP-PLUS */
				recorderManager = new Record();
				/* #endif */
				recorderManager.onStart(() => {
					console.log('recorder start');
				});
				recorderManager.onStop(res => {
					console.log('录音停止---------------');
				});
				recorderManager.onFrameRecorded(res => {
					// console.log('持续录音中,持续返回每帧的录音数据，以ArrayBuffer格式，基本常规解析语音的都是这个格式');
					const {
						frameBuffer
					} = res;
					//我的业务是通过websocket来发送解析语音的，具体看你的业务,发送录音数据的逻辑你根据你的业务去写

					asr?.send({
						data: frameBuffer,
						success: e => {
							// console.log('发送socket成功', e);
						},
						fail: err => {
							console.log('发送socket失败', err);
						},
						complete: res => {}
					});
				}); // 播放监听避免重复绑定
			},
			// 录音授权
			async getRecordAuth() {
				/* #ifdef MP-WEIXIN */
				await this.wxCheckRecordAuth(); // 检测微信小程序是否获取麦克风权限
				/* #endif */
				// #ifdef APP-PLUS
				const isIos = plus.os.name == 'iOS';
				if (!isIos) {
					// 安卓需要主动获取权限
					await authForApp('麦克风权限');
				}
				// #endif
			},

			async start() {
				// 开始录音前链接asr,超过15秒没发音频数据会自动断开
				asr.changeParams(this.asrParams)
				await asr?.open();
				// 等一秒初始化时间，可以在这个业务逻辑上添加ui 的loading
				await new Promise(resolve => setTimeout(resolve, 500));

				if (asr.type === 'tengxun' || asr.type === 'xunfei') {
					// 'frameSize'：int,//帧大小（必须，单位：字节）
					// 'sampleRate':int，//采样率（16000采样率插件写死16000）8000采样率插件的要写死8000
					// 'duration':number // 默认录音时间
					// 生成的录音格式一律是pcm，这种格式基本兼容所有市场的asr第三方
					// app端录音需要这是四个参数，其他参数内置好了默认值。不建议修改，因为这种配置比较稳定
					// 微信小程序端可以根据微信小程序文档自行写入参
					recorderManager.start({
						frameSize: 1024 * 5,
						duration: 30 * 60 * 1000,
						sampleRate: 16000,
						format: 'pcm'
					});
				}
			},
			stop: function() {
				console.log('停止开始', new Date());
				recorderManager.stop();
				asr?.close();
				this.recording = false;
				this.content = this.content + this.addContent;
				this.addContent = '';
			},
			// 检测微信是否有麦克风权限
			// 微信小程序麦克风权限常见问题：
			//{ "errMsg": "A:fail api scope is not declared in the privacy agreement",“errno": 112 } 使用到了 A隐私接口，但是开发者未在[mp后台-设置-服务内容声明-用户隐私保护指引]中声明收集 A接口对应的隐私类型。补充的隐私类型声明，将在5分钟后生效，
			wxCheckRecordAuth() {
				return new Promise((reslove, reject) => {
					uni.getSetting({
						success: res => {
							if (!res.authSetting['scope.record']) {
								console.log(123);
								uni.authorize({
									scope: 'scope.record',
									success: () => {
										// 用户已经同意小程序使用录音功能，后续调用 wx.startRecord 接口不会弹窗询问

										reslove(true);
									},
									fail: () => {
										uni.showModal({
											content: '检测到您没有打开麦克风权限，是否去设置打开?',
											cancelColor: '#666666',
											cancelText: '取消',
											confirmText: '确认',
											confirmColor: '#006DE7',

											success(res) {
												if (res.confirm) {
													uni.openSetting({
														success: res => {
															reslove(
																true
															);
														}
													});
												} else if (res.cancel) {
													reject(false);
												}
											}
										});
									}
								});
							} else {
								reslove(true);
							}
						}
					});
				});
			}
		}
	};
</script>